package com.matrix.async.core;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import com.matrix.async.service.AsyncTaskService;

public class ProducerFactoryBean implements InitializingBean, FactoryBean<Object> {

	@Autowired
	private AsyncTaskService asyncTaskService;

	private String taskType = null;

	private APPQueue taskQueue = null;

	private TaskHandler taskHandler = null;

	private int batchSize = 10;
	private ThreadFactory threadFactory = null;
	private RetryPolicy retryPolicy = null;
	private Map<?, ?> rushHour = new HashMap<>();
	private boolean randomInterval = true;
	private int interval = 30;
	private int rushHourInterval = 1;

	private int startupDelay = 0;
	private String beanUse = "false";

	private Producer thread = null;

	public ProducerFactoryBean() {
	}

	@Override
	public boolean isSingleton() {
		return false;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		checkData();
		thread = new Producer(taskType, taskQueue, taskHandler, asyncTaskService, threadFactory);
		thread.setBatchSize(batchSize);
		if (retryPolicy != null) {
			thread.setRetryPolicy(retryPolicy);
		}

		thread.setRushHour(rushHour);

		thread.setRandomInterval(randomInterval);

		if (interval > 0) {
			thread.setInterval(interval);
		}

		if (rushHourInterval > 0) {
			thread.setRunshHourInterval(rushHourInterval);
		}

		thread.setStartupDelay(startupDelay);

		thread.setBeanUse(beanUse);

	}

	private void checkData() {
		if (taskType == null) {
			throw new IllegalArgumentException("The parameter 'taskType' is necessary");
		}
		if (taskQueue == null) {
			throw new IllegalArgumentException("The parameter 'taskQueue' is necessary");
		}
		if (taskHandler == null) {
			throw new IllegalArgumentException("The parameter 'taskHandler' is necessary");
		}
	}

	public Object getObject() throws Exception {
		return thread;
	}

	@Override
	public Class<?> getObjectType() {
		return Producer.class;
	}

	public void setTaskType(String taskType) {
		this.taskType = taskType;
	}

	public void setTaskQueue(APPQueue taskQueue) {
		this.taskQueue = taskQueue;
	}

	public void setTaskHandler(TaskHandler taskHandler) {
		this.taskHandler = taskHandler;
	}

	public void setBatchSize(int batchSize) {
		if (batchSize <= 0) {
			throw new IllegalArgumentException("The paramenter 'bathSize' can't be less than 1 ");
		}
		this.batchSize = batchSize;
	}

	public void setThreadFactory(ThreadFactory threadFactory) {
		this.threadFactory = threadFactory;
	}

	public void setRetryPolicy(RetryPolicy retryPolicy) {
		this.retryPolicy = retryPolicy;
	}

	public void setRushHour(Map<?, ?> rushHour) {
		this.rushHour = rushHour;
	}

	public boolean isRandomInterval() {
		return randomInterval;
	}

	public void setRandomInterval(boolean randomInterval) {
		this.randomInterval = randomInterval;
	}

	public void setInterval(int interval) {
		this.interval = interval;
	}

	public void setRushHourInterval(int rushHourInterval) {
		this.rushHourInterval = rushHourInterval;
	}

	public void setStartupDelay(int startupDelay) {
		if (startupDelay <= 0) {
			throw new IllegalArgumentException("The paramenter 'startupDelay' can't be less than 1 ");
		}
		this.startupDelay = startupDelay;
	}

	public void setBeanUse(String beanUse) {
		this.beanUse = beanUse;
	}

}
